package shapes.shapes2D.distribution.poissondisk 
{
	import flash.display.BitmapData;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import shapes.shapes2D.Dot;
	import utils.GeomUtils;
	
	/**
	 * @author Nicolas Barradeau
	 * http://en.nicoptere.net
	 */
	public class PoissonDisk extends Sprite
	{
		static private var cellSize:Number;
		
		static private var min_dist_square:Number;
		
		static private var samplePoints:Vector.<Point>;
		
		public function PoissonDisk() 
		{
			
		}
		static public function distribute( rect:Rectangle, min_dist:Number = 10, count:int = 50 ):Vector.<Point>
		{
			
			
			min_dist_square = min_dist * min_dist;
			
			var max:int = ( rect.width / min_dist ) * ( rect.height / min_dist );
			
			if ( count > max * .5 ) count = max * .5;
			
			
			//var p:Point = new Point( Math.random() * rect.width, Math.random() * rect.height );
			var p:Point = new Point( rect.width / 2 , rect.height / 2 );
			var np:Point;
			
			samplePoints = Vector.<Point>( [ p ] );
			
			
			while ( samplePoints.length < count )
			{
				
				//np = generateRandomPointAround( samplePoints[ int( Math.random() * samplePoints.length ) ], min_dist );
				np = new Point( Math.random() * rect.width, Math.random() * rect.height );
				
				if ( rect.containsPoint( np ) )
				{
					if ( !isAround( samplePoints, np ) )
					{
						
						samplePoints.push( np );
						
					}
				}
			}
			
			return samplePoints;
		}
		
		
		static private function isAround( points:Vector.<Point>, np:Point ):Boolean
		{
			
			var p:Point;
			var dx:Number, dy:Number;
			var x:int, y:int;
			for each( p in points )
			{
				dx = np.x - p.x;
				dy = np.y - p.y;
				if ( ( dx * dx + dy * dy ) < min_dist_square ) return true;
			}
			
			return false;
		}
		
		static private function generateRandomPointAround( point:Point, mindist:Number ):Point
		{
			
			//random radius between mindist and 2 * mindist
			var radius:Number = mindist + ( mindist * Math.random() );
			
			//random angle
			var angle:Number = ( 2 * Math.PI ) * Math.random();
			
			//the new point is generated around the point (x, y)
			return new Point( 	point.x + radius * Math.cos(angle),
								point.y + radius * Math.sin(angle) 	);
		
		}
		
	}

}
	